package com.ebei.admin.controller;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.ebei.admin.common.constant.Constants;
import com.ebei.admin.common.constant.ErrorEnum;
import com.ebei.admin.common.util.CommonUtil;
import com.ebei.admin.common.util.DocUtil;
import com.ebei.admin.model.dto.UserDTO;
import com.ebei.admin.model.dto.UserExcelDTO;
import com.ebei.admin.model.dto.UserInfo;
import com.ebei.admin.model.entity.SysUser;
import com.ebei.admin.service.SysUserService;
import com.ebei.common.bean.config.FdfsPropertiesConfig;
import com.ebei.common.constant.CommonConstant;
import com.ebei.common.util.R;
import com.ebei.common.util.Result;
import com.ebei.common.vo.UserVO;
import com.ebei.common.web.BaseController;
import com.luhuiguo.fastdfs.domain.StorePath;
import com.luhuiguo.fastdfs.service.FastFileStorageClient;
import com.xiaoleilu.hutool.convert.Convert;
import com.xiaoleilu.hutool.io.FileUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.naming.Name;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/user")
@Slf4j
@Api(value = "用户", description = "用户接口")
public class UserController extends BaseController {

    private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();

    @Autowired
    private FastFileStorageClient fastFileStorageClient;
    @Autowired
    private SysUserService userService;
    @Autowired
    private FdfsPropertiesConfig fdfsPropertiesConfig;

    @ApiOperation(value = "获取用户详情", notes = "登陆获取用户详情（菜单等）")
    @GetMapping("/info")
    public Result<UserInfo> getUserInfo(UserVO userVo) {
        UserInfo userInfo = userService.findUserInfo(userVo, Boolean.TRUE);
        return new Result<>(userInfo, Result.SUCCESS, "获取成功");
    }

    /**
     * 通过ID查询当前用户信息
     *
     * @param id
     * @return 用户信息
     */
    @ApiOperation(value = "获取用户", notes = "根据ID获取用户")
    @ApiImplicitParam(name = "id", value = "用户ID", required = true)
    @GetMapping
    public UserVO selectById(@RequestParam Integer id) {
        return userService.selectUserVoById(id);
    }

    /**
     * 删除用户信息
     *
     * @param user
     * @return Result
     */
    @ApiOperation(value = "删除用户", notes = "根据ID删除用户")
    @ApiImplicitParam(name = "UserDTO", value = "用户值对象 ", required = true)
    @PostMapping("/delete")
    public Result<Boolean> userDel(@RequestBody UserDTO user) {
        SysUser sysUser = userService.selectById(user.getUserId());
        sysUser.setDelFlag(CommonConstant.STATUS_DEL);
        userService.updateById(sysUser);
        return Result.OK;
        //return new Result(userService.deleteUserById(sysUser), Result.SUCCESS);
    }

    /**
     * 添加用户
     *
     * @param userDto 用户信息
     * @return success/false
     */
    @ApiOperation(value = "新增用户", notes = "新增用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userAccount", value = "用户账号", required = true),
            @ApiImplicitParam(name = "userName", value = "用户名", required = false),
            @ApiImplicitParam(name = "telephone", value = "用户电话", required = false),
            @ApiImplicitParam(name = "password", value = "密码", required = false),
            @ApiImplicitParam(name = "orgId", value = "组织id", required = true),
            @ApiImplicitParam(name = "type", value = "人员类型", required = true),
            @ApiImplicitParam(name = "sex", value = "人员类型", required = true),
            @ApiImplicitParam(name = "workNum", value = "工号", required = true)
    })
    @PostMapping
    public Result user(@RequestBody UserDTO userDto) {
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(userDto, sysUser);
        boolean exist = userService.findUserByUserAccount(userDto.getUserAccount()) != null;
        if (exist) {
            return new Result(Result.FAIL, ErrorEnum.USER_EXIST);
        }
        sysUser.setDelFlag(CommonConstant.STATUS_NORMAL);
        sysUser.setPassword(ENCODER.encode(CommonConstant.DEFAULT_PASSWORD));
        sysUser.setCreateTime(new Date());
        sysUser.setAvatar(Constants.DEFAULT_AVATAR);
        sysUser.setSalt(CommonConstant.DEFAULT_SALT);
        userService.insert(sysUser);
        return Result.OK;
    }

    /**
     * 更新用户信息
     *
     * @param map 用户信息
     * @return Result
     */
    @ApiOperation(value = "修改用户", notes = "更新用户的信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户Id", required = true),
            @ApiImplicitParam(name = "userName", value = "用户名", required = false),
            @ApiImplicitParam(name = "orgId", value = "组织id", required = false),
            @ApiImplicitParam(name = "newPassword", value = "修改时的新密码", required = false),
            @ApiImplicitParam(name = "sex", value = "用户性别", required = false),
            @ApiImplicitParam(name = "type", value = "用户类型", required = false),
            @ApiImplicitParam(name = "telephone", value = "用户电话", required = false)
    })
    @PostMapping("/update")
    public Result userUpdate(@RequestBody Map<String, Object> map) throws Exception {
        SysUser user = userService.selectById(Convert.toStr(map.get("userId")));
        return userService.updateUser(map, user.getUserName());
    }

    /**
     * 通过用户名查询用户及其角色信息
     *
     * @param userAccount 用户名
     * @return UseVo 对象
     */
    @ApiOperation(value = "根据userAccount查询用户", notes = "根据account查询用户")
    @ApiImplicitParam(name = "userAccount", value = "用户account", required = true)
    @GetMapping("/findUserByUserAccount/{userAccount}")
    public UserVO findUserByUserAccount(@PathVariable String userAccount) {
        return userService.findUserByUserAccount(userAccount);
    }

    /**
     * 通过手机号查询用户及其角色信息
     *
     * @param mobile 手机号
     * @return UseVo 对象
     */
    @ApiOperation(value = "根据mobile查询用户", notes = "根据account查询用户")
    @ApiImplicitParam(name = "mobile", value = "用户手机号", required = true)
    @GetMapping("/findUserByMobile/{mobile}")
    public UserVO findUserByMobile(@PathVariable String mobile) {
        return userService.findUserByMobile(mobile);
    }

    /**
     * 通过OpenId查询
     *
     * @param openId openid
     * @return 对象
     */
    @ApiOperation(value = "根据openId查询用户", notes = "暂时没用吧,根据account查询用户")
    @ApiImplicitParam(name = "openId", value = "openID", required = true)
    @GetMapping("/findUserByOpenId/{openId}")
    public UserVO findUserByOpenId(@PathVariable String openId) {
        return userService.findUserByOpenId(openId);
    }

    /**
     * 分页查询用户
     *
     * @param params 参数集
     * @return 用户集合
     */
    @ApiOperation(value = "分页查询用户", notes = "分页查询用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orgId", value = "组织id", required = false),
            @ApiImplicitParam(name = "inputStr", value = "输入框内容", required = false)
    })
    @GetMapping("/page")
    public Result<Page> byPage(@RequestParam Map<String, Object> params) {
        CommonUtil.removeT(params);
        return userService.findByParam(params);
    }

    /**
     * 上传用户头像
     * (多机部署有问题，建议使用独立的文件服务器)
     *
     * @param file 资源
     * @return filename map
     */
    @ApiOperation(value = "上传文档", notes = "上传文件")
    @ApiImplicitParam(name = "file", value = "上传的文件", required = true)
    @PostMapping("/upload")
    public Result upload(@RequestParam("file") MultipartFile file) throws Exception {
        String fileExt = FileUtil.extName(file.getOriginalFilename());
        Map<String, String> resultMap = new HashMap<>(1);
        if (DocUtil.isExcel(file)) {
            userService.insertByList(DocUtil.importExcel(file, UserExcelDTO.class));
        } else {
            StorePath storePath = fastFileStorageClient.uploadFile(file.getBytes(), fileExt);
            //resultMap.put("filename", fdfsPropertiesConfig.getFileHost() + storePath.getFullPath());
            resultMap.put("filename", "http://chuantu.biz/t6/316/1526902021x-1404793154.jpg");
        }
        return Result.OK;
    }

    /**
     * 修改个人信息,,暂时没用
     *
     * @param userDto userDto
     * @param userVo  登录用户信息
     * @return success/false
     */
    @PostMapping("/editInfo")
    public R<Boolean> editInfo(@RequestBody UserDTO userDto, UserVO userVo) {
        return new R<>(userService.updateUserInfo(userDto, userVo.getUserName()));
    }

    @ApiOperation(value = "根据角色获取用户列表", notes = "角色管理页面级联人员列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleCode", value = "角色编码", required = true),
            @ApiImplicitParam(name = "inputStr", value = "输入内容", required = true)
    })
    @GetMapping("/getUsersByRole")
    public Result<List<Map<String, Object>>> getUsersByRole(@RequestParam Map<String, Object> params) {
        return new Result<>(userService.findUsersByRoleCondition(params), Result.SUCCESS, "获取成功");
    }

    @ApiOperation(value = "获取人员Excel模版")
    @GetMapping("/doc")
    public void exportExcel(HttpServletRequest request, HttpServletResponse response) throws Exception {
        DocUtil.exportExcel(response, UserExcelDTO.class, "人员Excel模版");
    }

    @ApiOperation(value = "禁用用户")
    @ApiImplicitParam(name = "userId", value = "用户id", required = true)
    @PostMapping("/lock")
    public Result setDisable(@RequestBody UserDTO user) {
        return userService.lock(user.getUserId());
    }

    @ApiOperation(value = "根据组织id获取在岗人(组织架构获取)")
    @ApiImplicitParam(name = "orgId", value = "组织id", required = true)
    @GetMapping("/findUserByOrgId")
    public Result findUserByOrgId(@RequestParam Integer orgId) {
        return userService.findUserByOrgId(orgId);
    }

    @ApiOperation(value = "根据组织id获取用户(用户表直接获取)")
    @ApiImplicitParam(name = "companyId", value = "用户所属公司或园区id", required = true)
    @GetMapping("/findUserByCompanyId")
    public Result getUserByCompanyId(@RequestParam Integer companyId) {
        SysUser condition = new SysUser();
        condition.setDelFlag(CommonConstant.STATUS_NORMAL);
        condition.setOrgId(companyId);
        List<SysUser> userList = userService.selectList(new EntityWrapper<>(condition));
        return new Result(userList, Result.SUCCESS, "获取成功");
    }

    @ApiOperation(value = "修改密码")
    @ApiImplicitParam(name = "UserDTO", value = "用户", required = true)
    @PostMapping("/pwdUpd")
    public Result<Boolean> pwdUpd(@RequestBody UserDTO userDTO){
        // 获取登陆用户
        SysUser condition = new SysUser();
        condition.setUserAccount(userDTO.getUserAccount());
        condition.setDelFlag(CommonConstant.STATUS_NORMAL);
        SysUser loginUser = userService.selectOne(new EntityWrapper<>(condition));
        // 验证用户、原密码
        if (loginUser == null) {
            return new Result<>(null, Result.FAIL, "用户不存在");
        }

        if (!CommonUtil.ENCODER.matches(userDTO.getPassword(), loginUser.getPassword())) {
            return new Result<>(null, Result.FAIL, "密码错误");
        }

        // 修改密码
        SysUser sysUser = new SysUser();
        sysUser.setUserId(loginUser.getUserId());
        sysUser.setPassword(ENCODER.encode(userDTO.getNewPassword()));
        if(userService.updateById(sysUser)){
            return new Result<>(Result.SUCCESS,"修改密码成功");
        }else{
            return new Result<>(Result.FAIL,"修改密码失败");
        }
    }

    @ApiOperation(value = "条件获取用户 设备用")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "页码,默认第一页", required = false),
            @ApiImplicitParam(name = "limit", value = "每页条数,默认十条", required = false),
            @ApiImplicitParam(name = "companyId", value = "公司id", required = false),
            @ApiImplicitParam(name = "userType", value = "用户类型(comm,admin)", required = false)
    })
    @GetMapping("/getUsersForDevice")
    public Result<Page> getUsersForDevice(@RequestParam Map<String,Object> params){
        return userService.getUsersForDevice(params);
    }

}